//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include "ddk.h"
#include <stdio.h>
#include <stdlib.h>
#include "misc.h"
#include <llist.h>

/*
 * ll_init()
 *    Initialize list head
 */
EXTERN_C Void ll_init(struct llist *l)
{
    l->l_forw = l->l_back = l;
#ifdef DEBUG
    l->l_data = 0;
#endif
}

/*
 * ll_insert()
 *    Insert datum at list head in list
 *
 * Returns new node, or 0 for failure
 */
EXTERN_C struct llist *ll_insert(struct llist *l, void *d)
{
    struct llist *lnew;
    struct llist *l_forw = l->l_forw;

    lnew = (struct llist *)malloc(sizeof(struct llist));
    if (lnew == 0)
        return 0;
    lnew->l_data = d;

    lnew->l_forw = l_forw;
    lnew->l_back = l;
    l_forw->l_back = lnew;
    l->l_forw = lnew;
    return(lnew);
}

/*
 * ll_delete()
 *    Remove node from linked list, free storage
 */
EXTERN_C Void ll_delete(struct llist *l)
{
    struct llist *l_forw = l->l_forw;
    struct llist *l_back = l->l_back;

    l_back->l_forw = l_forw;
    l_forw->l_back = l_back;
#ifdef DEBUG
    l->l_forw = l->l_back = 0;
    l->l_data = 0;
#endif
    free(l);
}

/*
 * ll_movehead()
 *    Move head of list to place within
 */
EXTERN_C Void ll_movehead(struct llist *head, struct llist *l)
{
    struct llist *l_back;
    struct llist *l_forw;
    struct llist *head_forw = head->l_forw;

    if (head_forw == l) {
        return;
    }
    l_back = l->l_back;
    l_forw = l->l_forw;
    l_back->l_forw = l_forw;
    l_forw->l_back = l_back;
    l->l_forw = head_forw;
    l->l_back = head;
    head_forw->l_back = l;
    head->l_forw = l;
}
